module FeedmeTags
  include Radiant::Taggable
  
  class TagError < StandardError; end
  
  tag 'feed' do |tag|
    tag.expand
  end
  
  tag 'feed:entries' do |tag|
    tag.expand
  end
  
  desc %{
    Iterates through feed's entries/items (atom/rss).
    
    *Usage:*
    <pre><code><r:feed:entries:each feedname="my_feed">
      ...
    </r:feed:entries:each>
    </code></pre>
  }
  tag 'feed:entries:each' do |tag|
    raise TagError, "You have to specify feed name." unless tag.attr['feedname']
    raise TagError, "Feed does not exist." unless tag.locals.feed = Feed.find_by_name(tag.attr['feedname'])
    
    result = []
    
    case tag.locals.feed[:kind]
      when "atom" then
        entries = tag.locals.feed.data.get_elements("feed/entry")
      when "rss"  then
        entries = tag.locals.feed.data.get_elements("channel/item")
      when "ical" then
        entries = tag.locals.feed.data.events
        entries.delete_if { |e| (e.end || e.start || DateTime.now) < DateTime.now } if tag.attr['only'] == "upcoming"
    end
    entries.reverse! if tag.attr['order'] == "asc"
    entries = entries.slice( ((@request.parameters["page"] || "1").to_i-1)*tag.attr["limit"].to_i, tag.attr["limit"].to_i ) if tag.attr["limit"]
    entries.each do |entry| 
      tag.locals.entry = entry
      result << tag.expand
    end
    result
  end
  
  desc %{
    Works only with *ATOM/RSS* feeds!
    
    Gives access to item's/entry's text nodes or attributes.
    
    In @query@ attribute you can specify <a href="http://www.w3schools.com/xpath/default.asp" target="_blank">XPath</a> query, which will return
    first found text node or attribute value. You can also get attribute's value
    using @attribute@ attribute.
    
    *Usage:*
    <pre><code><r:feed:entries:each feedname="my_feed">
      ...
      <r:entry query="media:group/media:thumbnail[1]" attribute="url" />
      ...
    </r:feed:entries:each>
    </pre><code>
  }
  tag 'feed:entries:each:entry' do |tag|
    raise TagError, "Works only with ATOM/RSS feeds!" if tag.locals.feed[:kind] == "ical" 
    
    entry = tag.locals.entry
    if tag.attr['query']
      if tag.attr['attribute']
        entry.elements[tag.attr['query']].attributes[tag.attr['attribute']]
      else
        entry.elements[tag.attr['query']].text
      end
    else
      title = entry.elements["title"].text
      href = entry.elements["link[@type='text/html']"].attributes["href"]
      %{<a href="#{href}">#{title}</a>}
    end
  end
  
  desc %{
    Works only with *iCal* feeds!
    
    Gives access to event's properties.
    
    You have to specify @property@ attribute as in <a href="http://icalendar.rubyforge.org/classes/Icalendar/Event.html" target="_blank">iCalendar's Event</a> documentation.
    When requesting date/time information, you also specify @format@ attribute.
    
    *Usage:*
    <pre><code><r:feed:entries:each feedname="my_ical_feed">
      ...
      <r:event property="summary" />
      ...
    </r:feed:entries:each>
    </pre><code>
  }
  tag 'feed:entries:each:event' do |tag|
    raise TagError, "Works only with ATOM/RSS feeds!" unless tag.locals.feed[:kind] == "ical"
    raise TagError, "You have to specify feed name." unless tag.attr['property']
    
    if prop = eval("tag.locals.entry."+tag.attr['property'])
      case prop.class.to_s
        when "DateTime"
          format = (tag.attr['format'] || '%A, %B %d, %Y, %H:%M')
          prop.strftime(format)
        else
          prop.to_s
      end
    end
  end
  
  desc %{
    Gives entry's/item's/event's title.
  }
  tag 'feed:entries:each:title' do |tag|
    unless tag.locals.feed[:kind] == "ical"
      tag.locals.entry.elements["title"].text
    else
      tag.locals.entry.summary
    end
  end

  tag 'feed:entries:each:if_event' do |tag|
    raise TagError, "Works only with ATOM/RSS feeds!" unless tag.locals.feed[:kind] == "ical"
    raise TagError, "You have to specify feed name." unless tag.attr['property']
    
    tag.expand if eval("tag.locals.entry."+tag.attr['property'])
  end
  
  tag 'feed:entries:each:unless_event' do |tag|
    raise TagError, "Works only with ATOM/RSS feeds!" unless tag.locals.feed[:kind] == "ical"
    raise TagError, "You have to specify feed name." unless tag.attr['property']
    
    tag.expand unless eval("tag.locals.entry."+tag.attr['property'])
  end
    
end